package edu.mse.camel.client.whiteboard.gef.ui.commands;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.requests.ChangeBoundsRequest;

import edu.mse.camel.client.whiteboard.gef.whiteboard.FreeWritingShape;

public class FreeWritingShapeSetConstraintCommand extends AbstractWhiteboardCommand {

	/** Stores the new size and location. */
	private final Rectangle newBounds;
	/** Stores the old size and location. */
	private Rectangle oldBounds;
	/** A request to move/resize an edit part. */
	private final ChangeBoundsRequest request;
	
	/** Shape to manipulate. */
	private final FreeWritingShape shape;
	
	/**
	 * Create a command that can resize and/or move a shape. 
	 * @param shape	the shape to manipulate
	 * @param req		the move and resize request
	 * @param newBounds the new size and location
	 * @throws IllegalArgumentException if any of the parameters is null
	 */
	public FreeWritingShapeSetConstraintCommand(FreeWritingShape shape, ChangeBoundsRequest req, 
			Rectangle newBounds) {
		if (shape == null || req == null || newBounds == null) {
			throw new IllegalArgumentException();
		}
		this.shape = shape;
		this.request = req;
		this.newBounds = newBounds.getCopy();
		setLabel("move / resize");
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#canExecute()
	 */
	public boolean canExecute() {
		Object type = request.getType();
		// make sure the Request is of a type we support:
		return (RequestConstants.REQ_MOVE.equals(type)
				|| RequestConstants.REQ_MOVE_CHILDREN.equals(type));
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	public void execute() {
		oldBounds = new Rectangle(
				shape.getLocation().x,
				shape.getLocation().y, 
				shape.getSize().width, 
				shape.getSize().height);
		redo();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#redo()
	 */
	public void redo() {
		Point location = new Point(newBounds.x, newBounds.y);
		shape.setLocation(location);
		Dimension size = new Dimension(newBounds.width, newBounds.height);
		shape.setSize(size);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	public void undo() {
		Point location = new Point(oldBounds.x, oldBounds.y);
		shape.setLocation(location);
		Dimension size = new Dimension(oldBounds.width, oldBounds.height);
		shape.setSize(size);
	}
}
